#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "llist.h"
/*
struct llist_node_st
{
	struct llist_node_st *prev;
	struct llist_node_st *next;
	char data[0];
};
typedef struct{
	int size;//数据部分大小
	struct llist_node_st head;//链表的头结点
}LLIST;
*/
LLIST * llist_create(int size)
{
	LLIST *new;
	new=malloc(sizeof(*new));
	if(new==NULL)
	{
		return NULL;
	}
	new->size=size;
	new->head.prev=new->head.next=&new->head;
	return new;
}
int llist_insert(LLIST *ptr,const void *data,int mode)
{
	struct llist_node_st *newnode;
	newnode=malloc(sizeof(struct llist_node_st)+ptr->size);
	if(newnode==NULL)
	{
		return -1;
	}
	memcpy(newnode->data,data,ptr->size);
	
	
	if(mode==LLIST_FORWARD)
	{
		newnode->prev=&ptr->head;
		newnode->next=ptr->head.next;
	}
	else if(mode==LLIST_BACKWARD)
	{
		newnode->prev=ptr->head.prev;
		newnode->next=&ptr->head;
	}
	newnode->prev->next=newnode;
	newnode->next->prev=newnode;
	return 0;
}

void llist_travel(LLIST *ptr,void (*llist_op)(void *))
{
	struct llist_node_st *cur;
	for(cur=ptr->head.next;cur!=&ptr->head;cur=cur->next)
	{
		llist_op(cur->data);
	}

}
static struct llist_node_st * find__(LLIST *ptr,const void *key,int (*cmp)(const void *,const void *))
{
	struct llist_node_st *cur;
	for(cur=ptr->head.next;cur!=&ptr->head;cur=cur->next)
	{
		if(cmp(key,cur->data)==0)
		{
			break;
		}
	}
	return cur;
}
void * llist_find(LLIST *ptr,const void *key,int (*cmp)(const void *,const void *))
{
	struct llist_node_st *node;
	node=find__(ptr,key,cmp);
	if(node==&ptr->head)
	{
		return NULL;
	}
	return node->data;
}
int llist_delete(LLIST *ptr,const void *key,int (*cmp)(const void *,const void *))
{
	struct llist_node_st *cur;
	cur=find__(ptr,key,cmp);
	if(cur!=&ptr->head)
	{
			cur->prev->next=cur->next;
			cur->next->prev=cur->prev;
			free(cur);
			return 0;
	}
	return -1;
}
int llist_fetch(LLIST *ptr,const void *key,void * data,int (*cmp)(const void *,const void *))
{
	struct llist_node_st *cur;
	cur=find__(ptr,key,cmp);
	if(cur!=&ptr->head)
	{
			memcpy(data,cur->data,ptr->size);
			cur->prev->next=cur->next;
			cur->next->prev=cur->prev;
			free(cur);
			return 0;
	}
	return -1;
}

void llist_destroy(LLIST *ptr)
{
	struct llist_node_st *cur,*save;
	for(cur=ptr->head.next;cur!=&ptr->head;cur=save)
	{
		save=cur->next;
		free(cur);
	}
	free(ptr);
}








